import { login, logout, getInfo } from "@/api/user"
import { getToken, setToken, removeToken } from "@/utils/auth"
import { resetRouter } from "@/router"

const getDefaultState = () => {
  return {
    token: getToken(),
    name: "",
    avatar: ""
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  }
}

const actions = {
  /**
   * 用户登录
   * @param context 上下文对象
   * @param userInfo 用户信息
   */
  login(context, userInfo) {
    const { commit } = context
    const { username, password } = userInfo
    
    return new Promise((resolve, reject) => {
      login(username.trim(), password).then(
        response => {
          const { token } = response
          
          commit("SET_TOKEN", token)
          setToken(token)
          
          resolve()
        }
      ).catch(
        error => {
          reject(error)
        }
      )
    })
  },
  
  /**
   * 获取用户信息
   * @param context 上下文对象
   */
  getInfo(context) {
    const { commit } = context
    
    return new Promise((resolve, reject) => {
      getInfo().then(
        response => {
          if (!response) return reject("Verification failed, please Login again.")
          
          const { name, avatar } = response
          
          commit("SET_NAME", name)
          commit("SET_AVATAR", avatar)
          
          resolve(response)
        }
      ).catch(
        error => {
          reject(error)
        }
      )
    })
  },
  
  /**
   * 登出
   * @param context 上下文对象
   */
  logout(context) {
    const { commit, state } = context
    
    return new Promise((resolve, reject) => {
      logout(state.token).then(
        () => {
          removeToken()
          resetRouter()
          
          commit("RESET_STATE")
          
          resolve()
        }
      ).catch(
        error => {
          reject(error)
        }
      )
    })
  },
  
  /**
   * 清除 token
   * @param context 上下文对象
   */
  resetToken(context) {
    const { commit } = context
    
    return new Promise(resolve => {
      removeToken()
      
      commit("RESET_STATE")
      
      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
